import OutStream, InStream from "Builtins"
export runtest to "RunTest"

const runtest == immutable object runtest
  export create, getSignature
  const runTestType == type runTestType
    operation finish [Boolean]
    operation done
    operation check  [Boolean, String]
  end runTestType
  function getSignature -> [r : Signature]
    r <- runTestType
  end getSignature
  operation create [in : InStream, out : OutStream, testName : String] -> [r : runTestType]
    r <- object aRunTest
      export finish, check, done
      monitor
	var firstCheckMessagePrinted : Boolean <- false
	var success : Boolean <- true
	operation finish [result : Boolean]
	  if testname !== nil then
	    if firstCheckMessagePrinted then
	      out.PutString["Test \""]
	      out.PutString[testname]
	      out.PutString["\""]
	    end if
	    if result then
	      out.PutString[" completed successfully.\^J"]
	    else
	      out.PutString[" failed.\^J"]
	    end if
	  end if
	  in.close
	  out.close
	end finish
	operation check [b : Boolean, test : String]
	  success <- success & b
	  if ! b then
	    if ! firstCheckMessagePrinted then
	      out.PutString["\^J"]
	      firstCheckMessagePrinted <- true
	    end if
	    out.PutString["  Test \""]
	    out.PutString[test]
	    out.PutString["\" failed.\^J"]
	  end if
	end check
	function getSuccess -> [r : Boolean]
	  r <- success
	end getSuccess
	initially
	  if testname !== nil then
	    out.PutString["Test \""]
	    out.PutString[testname]
	    out.PutString["\" starting ..."]
	    out.flush
	  end if
	end initially
      end monitor
      operation done 
	finish[getSuccess[]]
      end done
    end aRunTest
  end create
end runtest
